package com.tank.model;

import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.Random;

import com.tank.designstudy.strategy.DefaultFireStrategy;
import com.tank.designstudy.strategy.FireStrategy;
import com.tank.resource.ResourceLoader;

/**
 * @author 孙哈哈 封装坦克类 1.1 增加运动状态属性 moving 为true时表示运动
 */
public class Tank extends GameObject {
    // x,y 分别代表坦克当前位置 通过改变其值，可以在画面重新绘制时刷新坦克位置
    private int x, y;
    private int oldX, oldY;
    // 坦克行进速度
    private int SPEED;
    // 坦克行进方向 初始方向向上
    private DirEnum dir = DirEnum.UP;
    // 运动状态
    private boolean moving = false;
    // 持有窗口类 -更改为持有GameModel类  tankframe只负责展示，不应该维护游戏逻辑
    //private GameModel gameModel;
    // 坦克宽高
    public static final int WIDTH = ResourceLoader.vip_bad_tankD.getWidth();
    public static final int HEIGHT = ResourceLoader.vip_bad_tankD.getHeight();
    // 是否存活
    public boolean living = true;
    // 游戏分组 默认为敌方
    private GroupEnum group = GroupEnum.BAD;
    // 随机数 用于敌方随机打出炮弹
    private Random random = new Random();
    // 子弹边界
    private Rectangle rectangle = new Rectangle();

    private DirEnum[] dirs = {DirEnum.UP, DirEnum.RIGHT, DirEnum.DOWN, DirEnum.LEFT};

    // 方向盒  存放位置  用于随机坦克方向
    public Tank(int x, int y, int sPEED, GroupEnum group) {
        super();
        this.x = x;
        this.y = y;
        SPEED = sPEED;
        this.group = group;
        updateRectanglePosition(this.rectangle);
        if (group.equals(GroupEnum.BAD)) {
            this.moving = true;
            // 坦克实例化时自动加入到gamemodel中
            GameModel.INSTANCE.addGameObject(this);
        }else{
            GameModel.INSTANCE.setTank1(this);
        }
    }

    /**
     * 更新子弹矩形模型
     *
     * @param rectangle
     */
    private void updateRectanglePosition(Rectangle rectangle) {
        rectangle.width = Tank.WIDTH;
        rectangle.height = Tank.HEIGHT;
        rectangle.x = this.x;
        rectangle.y = this.y;
    }

    @Override
    public void paint(Graphics g) {
        if (!this.living) {
            return;
        }
        switch (dir) {
            // TODO 坦克增加闪烁效果
            case LEFT:
                g.drawImage(
                    this.group.equals(GroupEnum.BAD) ? ResourceLoader.vip_bad_tankL : ResourceLoader.vip_main_tankL,
                    x, y, null);
                break;
            case RIGHT:
                g.drawImage(
                    this.group.equals(GroupEnum.BAD) ? ResourceLoader.vip_bad_tankR : ResourceLoader.vip_main_tankR,
                    x, y, null);
                break;
            case UP:
                g.drawImage(
                    this.group.equals(GroupEnum.BAD) ? ResourceLoader.vip_bad_tankU : ResourceLoader.vip_main_tankU,
                    x, y, null);
                break;
            case DOWN:
                g.drawImage(
                    this.group.equals(GroupEnum.BAD) ? ResourceLoader.vip_bad_tankD : ResourceLoader.vip_main_tankD,
                    x, y, null);
                break;
            default:
                break;
        }
        // 调用坦克移动方法
        move();
    }

    @Override
    public boolean getLiving() {
        return this.living;
    }

    /**
     * 动作方法-移动坦克 通过改变坦克坐标和画面刷新实现坦克移动
     */
    private void move() {
        oldX = x;
        oldY = y;
        if (!moving) {
            return;
        }
        switch (dir) {
            case LEFT:
                x = x - SPEED;
                break;
            case RIGHT:
                x = x + SPEED;
                break;
            case UP:
                y = y - SPEED;
                break;
            case DOWN:
                y = y + SPEED;
                break;
            default:
                break;
        }

        // 边界检测
        boudaryDetection();

        // 更新坦克矩形模型
        updateRectanglePosition(this.rectangle);

        // 敌方坦克会有移动时随机打出炮弹的行为
        if (this.group.equals(GroupEnum.BAD)) {
            int randomToLevel10 = this.random.nextInt(10);
            int randomToLevel4 = this.random.nextInt(4);
            if (randomToLevel10 >= 8) {
                fire(DefaultFireStrategy.getInstance());
            }
            if (randomToLevel10 >= 9) {
                this.dir = dirs[randomToLevel4];
            }
        }
    }

    /**
     * 边界检测
     */
    private void boudaryDetection() {
        if (this.x <= 0) {
            x = 0;
        }
        if (this.y <= 0) {
            y = 0;
        }
        if (this.x >= GameModel.GAME_WIDTH - Tank.WIDTH) {
            x = GameModel.GAME_WIDTH - Tank.WIDTH;
        }
        if (this.y >= GameModel.GAME_HEIGHT - Tank.HEIGHT) {
            y = GameModel.GAME_HEIGHT - Tank.HEIGHT;
        }
    }

    /**
     * 发射子弹
     */
    public void fire(FireStrategy strategy) {
        int realW = this.x + Tank.WIDTH / 2 - Bullet.WIDTH / 2;
        int realH = this.y + Tank.HEIGHT / 2 - Bullet.HEIGHT / 2;
        GameModel.INSTANCE.addGameObject(new Bullet(realW, realH + 5, this.dir, this.group));
        strategy.fire(this);
    }

    /**
     * 用于碰撞时使坦克解除相持
     */
    /*public void setOppoSiteDir() {
        DirEnum current = this.dir;
        DirEnum tarDir = null;
        switch (current){
            case UP:
                tarDir = DirEnum.DOWN;
                break;
            case DOWN:
                tarDir = DirEnum.UP;
                break;
            case LEFT:
                tarDir = DirEnum.RIGHT;
                break;
            case RIGHT:
                tarDir = DirEnum.LEFT;
                break;
            default:
                break;
        }
        this.dir = tarDir;
    }*/
    public void moveBack() {
        x = oldX;
        y = oldY;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public DirEnum getDir() {
        return dir;
    }

    public void setDir(DirEnum dir) {
        this.dir = dir;
    }

    public void setMoving(boolean moving) {
        this.moving = moving;
    }

    public GroupEnum getGroup() {
        return group;
    }

    public Rectangle getRectangle() {
        return rectangle;
    }

    @Override
    public String toString() {
        return "Tank{" +
            "x=" + x +
            ", y=" + y +
            ", SPEED=" + SPEED +
            ", dir=" + dir +
            ", moving=" + moving +
            ", living=" + living +
            ", group=" + group +
            ", random=" + random +
            ", rectangle=" + rectangle +
            '}';
    }
}
